#include "local_main.h"
#include "local_lock.h"
#include "stdbool.h"
#include "component.h"
#include "menu.h"
#include "local_sub.h"

#define LOCAL_LOCK_LOG(format, ...) OSAL_LOG(C_YELLOW format C_NONE, ##__VA_ARGS__)
#define __LOCAL_LOCK_LOG(format, ...) __OSAL_LOG(C_YELLOW format C_NONE, ##__VA_ARGS__)

/* 锁体信息 */
__EFRAM static struct
{
    LockAction_enum_t lock_status; //锁状态
    UserAction_enum_t door_status; //门状态
    bool unlock_back;              //开锁回拖状态 true：已回拖，false：未回拖
    bool antiLockFlag;             //正在反锁标志
    uint8_t lock_type;             //锁体类型
    uint32_t auto_lock_time;       //自动上锁时间(ms)
    uint8_t userType;              //当前正在操作锁体的密钥类型：密码、卡片、指纹、锁体空闲时为0XFF
    uint8_t user_id;               //当前正在操作锁体的密钥编号
    uint8_t app_id;
    uint8_t event_code;
} lockInfo;

static TimerHandle_stu_t lock_timer = NULL;      //自动上锁定时器
static TimerHandle_stu_t unlockBackTimer = NULL; //开锁自动回拖定时器

__EFRAM static uint8_t sleepAutoLockedFlag = 1; // 休眠自动上锁标志
__EFRAM static FlagStatus wakePullbackFlag = RESET;  //唤醒回拖标志

static uint32_t autoLockStartTime = 0; //自动上锁开始计时时间
static uint32_t autoLockRemainTime = 0; //自动上锁剩余时间  ---- 用于休眠检测自动上锁时间，到时间直接唤醒处理自动上锁
static TimerHandle_stu_t updataRemainTime_timer = NULL;//自动上锁剩余时间更新定时器
#define AUTO_UPDATE_TIME 1000 

static void Local_LockAutoLockCallback(TimerHandle_stu_t timer);

/**
  * @brief  自动上锁剩余时间处理
  * @note   
  *
  * @return void
  */
static void Local_LockRemainTimeUpdateCallback(TimerHandle_stu_t timer)
{
    uint32_t currentTime = OSAL_GetTickCount();

    LOCAL_LOCK_LOG("update Callback startTime: %d, currentTime: %d, remaingTime: %d\r\n", autoLockStartTime, currentTime, autoLockRemainTime);

    if (lockInfo.lock_status != LOCK_ACTION_LOCKED && lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH && OSAL_PastTime(currentTime, autoLockStartTime) >= lockInfo.auto_lock_time)
    {
        LOCAL_LOCK_LOG("Auto locked2\r\n");
        OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
        Local_LockControl(LOCKED_TIMING, 0XFF, LOCK_CTRL_LOCKED);

        autoLockStartTime = 0; 
        autoLockRemainTime = 0;
        if (updataRemainTime_timer != NULL)
        {
            OSAL_TimerDelete(updataRemainTime_timer);
            updataRemainTime_timer = NULL;
        }
    }
    else
    {
        if (autoLockRemainTime <= KOS_PARAM_WAKE_INTERVAL)  // 剩余时间小于休眠唤醒间隔，直接用定时上锁定时器处理自动上锁
        {
            if (lock_timer != NULL)
            {
                OSAL_TimerDelete(lock_timer);
                lock_timer = NULL;
            }

            // 此定时器禁止进入休眠
            LOCAL_LOCK_LOG("create auto locked timer1\r\n");
            lock_timer = OSAL_TimerCreate(Local_LockAutoLockCallback, autoLockRemainTime, RESET);

            autoLockStartTime = 0;
            autoLockRemainTime = 0;
            if (updataRemainTime_timer != NULL)
            {
                OSAL_TimerDelete(updataRemainTime_timer);
                updataRemainTime_timer = NULL;
            }
        }
        else
        {
            autoLockRemainTime -= AUTO_UPDATE_TIME;
        }
        
    }

}

/**
  * @brief  休眠状态下自动上锁剩余时间处理
  * @note   
  *
  * @return void
  */
uint32_t wakeUpCheckRemainTime(void)
{
    if (autoLockRemainTime != 0)
    {
        uint32_t currentTime = OSAL_GetTickCount();
        autoLockRemainTime = lockInfo.auto_lock_time - OSAL_PastTime(currentTime, autoLockStartTime);

        LOCAL_LOCK_LOG("wake remainTime:%d currentTime:%d autoLockStartTime:%d autoLockRemainTime:%d\r\n", autoLockRemainTime, currentTime, autoLockStartTime, lockInfo.auto_lock_time);
        if (autoLockRemainTime < KOS_PARAM_WAKE_INTERVAL)
        {
            // 剩余时间不足等到下一次唤醒间隔，唤醒系统准备自动上锁
            LOCAL_LOCK_LOG("wake autoLock\r\n");
            return 1;
        }
    }
    
    return 0;
}

//自动上锁回调
static void Local_LockAutoLockCallback(TimerHandle_stu_t timer)
{
    LOCAL_LOCK_LOG("Local_LockAutoLockCallback door_status: %d, lock_status: %d\r\n", lockInfo.door_status, lockInfo.lock_status);
    if (Local_LockGetAmMode() == AUTO_MODE)
    {
        if (lockInfo.lock_status != LOCK_ACTION_LOCKED && lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH && lockInfo.door_status != USER_ACTION_RELEASE)
        {
            LOCAL_LOCK_LOG("Auto locked\r\n");
            OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
            Local_LockControl(LOCKED_TIMING, 0XFF, LOCK_CTRL_LOCKED);//   LOCKED_TYPE_10S
        }
        autoLockStartTime = 0;
        autoLockRemainTime = 0;
    }
    else
    {
        // Audio_Play(MEN_WEI_SHANG_SUO, 2);
        // Local_LockControl(0xff, 0xff, LOCK_CTRL_UNLOCK_BACK);
    }
    if (lock_timer != NULL)
    {
        OSAL_TimerDelete(lock_timer);
        lock_timer = NULL;
    }
}

//启动自动上锁定时器
static void Local_LockAutoLocked(uint8_t autoLockTime)
{
    if (lock_timer != NULL)
    {
        OSAL_TimerDelete(lock_timer);
        lock_timer = NULL;
    }

    if (Local_LockGetAmMode() == AUTO_MODE && lockInfo.door_status != USER_ACTION_RELEASE)
    {
        if (autoLockTime == 0xff)
        {
            // 默认自动上锁时间
            if (lockInfo.auto_lock_time > DEFAULT_AUTO_LOCK_TIME * 1000)
            {
                autoLockStartTime =  OSAL_GetTickCount();
                autoLockRemainTime = lockInfo.auto_lock_time;
                LOCAL_LOCK_LOG("auto_lock_time more than 10:%d\r\n", lockInfo.auto_lock_time);

                // 停止后板检测开锁唤醒
                Lock_SetSleepSenserCheck(RESET);
                if (updataRemainTime_timer != NULL)
                {
                    OSAL_TimerDelete(updataRemainTime_timer);
                    updataRemainTime_timer = NULL;
                }
                // 1S定时器更新剩余时间
                updataRemainTime_timer = OSAL_TimerCreate(Local_LockRemainTimeUpdateCallback, AUTO_UPDATE_TIME, SET);

            }
            else
            {
                lock_timer = OSAL_TimerCreate(Local_LockAutoLockCallback, lockInfo.auto_lock_time, RESET);
            }
        }
        else
        {
            // autoLockTime 自动上锁定时器时间
            lock_timer = OSAL_TimerCreate(Local_LockAutoLockCallback, autoLockTime * 1000, RESET);
        }
        LOCAL_LOCK_LOG("create auto locked timer:%d %d\r\n", lock_timer, autoLockTime);
        LOCAL_LOCK_LOG("lockInfo.auto_lock_time:%d\r\n", lockInfo.auto_lock_time);
    }
    else
    {
        LOCAL_LOCK_LOG("manual mode\r\n");
    }
}

//取消自动上锁
static void Local_LockCancelAutoLock(void)
{
    LOCAL_LOCK_LOG("Local_LockCancelAutoLock: %d\r\n", lock_timer);
    if (lock_timer != NULL)
    {
        OSAL_TimerDelete(lock_timer);
        lock_timer = NULL;
        LOCAL_LOCK_LOG("Cancel auto lock\r\n");
    }
}

//开锁自动回拖
static void Local_LockAutoUnlockBackCallback(TimerHandle_stu_t timer)
{
    LOCAL_LOCK_LOG("Auto unLock back lockInfo.lock_status:%d ,unlock_back %d\r\n", lockInfo.lock_status, lockInfo.unlock_back);
    if (lockInfo.lock_status == LOCK_ACTION_UNLOCK_NO_BACK && lockInfo.unlock_back == false)
    {
        LOCAL_LOCK_LOG("Auto unLock back\r\n");
        lockInfo.unlock_back = true;
        Local_LockControl(LOCKED_TYPE_10S, 0XFF, LOCK_CTRL_UNLOCK_BACK); //开锁回拖
        OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
    }
    if (unlockBackTimer != NULL)
    {
        OSAL_TimerDelete(unlockBackTimer);
        unlockBackTimer = NULL;
    }
    Local_LockAutoLocked(0xff);
}

//启动自动回拖
static void Local_LockUnLockBack(void)
{
    uint8_t closeTime = 3;
    LOCAL_LOCK_LOG("Start %ds auto unlocked back\r\n", closeTime);
    if (unlockBackTimer != NULL)
    {
        OSAL_TimerDelete(unlockBackTimer);
        unlockBackTimer = NULL;
    }
    unlockBackTimer = OSAL_TimerCreate(Local_LockAutoUnlockBackCallback, closeTime * 1000, RESET);
}

//退出系统锁定
static void local_LockExitSystemLock(void)
{
    uint8_t verifyErrCount = 0;
    OSAL_NvWrite(SYS_OFFSET(verifyErrCount), &verifyErrCount, sizeof(verifyErrCount));
}

//处理开锁成功
static void Local_UnlockSucceed(uint8_t userType, uint8_t keysNum)
{
    if (lockInfo.lock_status == LOCK_ACTION_INVALID && lockInfo.userType == 0xff) //首次上电
    {
        LOCAL_LOCK_LOG("First porwer on, return\r\n");
        return;
    }
     Beep_Set(1, 500); //响一声
    __EFRAM static uint8_t firstLowPower = true; //第一次低电量标志
    LOCAL_LOCK_LOG("Unlock succeed, userType:0X%02X, keysNum:%d\r\n", userType, keysNum);
    /* 低电量本地播放报警音 */
    uint8_t bat = SYS_CALL(Battery_Get);
    LOCAL_LOCK_LOG("bat is %d\r\n", bat);
    if ((bat <= BATTERY_LOW_POWER_I) || (bat <= BATTERY_LOW_POWER_II && firstLowPower == true)) //低电量
    {
        Local_LockSaveRecord(EVENT_TYPE_ALARM, 0XFF, EVENT_CODE_LOW_POWER, 0XFF);
        Audio_Play(DIAN_CHI_DIAN_LIANG_BU_ZU_QING_GENG_HUAN_DIAN_CHI, RESET);
        Oled_PopUpDisplay(POPUPS_LowPower,POPUPS_NULL,POP_UP_WINDOW_TIME);
        if (firstLowPower == true)
        {
            firstLowPower = false;
        }

        if (bat <= BATTERY_LOW_POWER_II)
        { 
            Led_Set("LED_BAT", LED_OFF, 0, 0);
            Led_Set("LED_LP", LED_FLASH, 0xff, 1000);
        }
        else
        {  
            Led_Set("LED_BAT", LED_ON, 0, 0);
            Led_Set("LED_LP", LED_OFF, 0, 0);
        }
    }
    else if (bat > BATTERY_LOW_POWER_I && bat <= BATTERY_LOW_POWER_II)
    {
        Local_LockSaveRecord(EVENT_TYPE_ALARM, 0XFF, EVENT_CODE_LOW_POWER, 0XFF);
    }

    if (userType == USERS_TYPE_PWD || userType == USERS_TYPE_FPT || userType == USERS_TYPE_CARD || userType == USERS_TYPE_FACE || userType == USERS_TYPE_APP)
    {
        //Audio_Play(QING_KAI_MEN, RESET);
        LocalSub_SetAlarm(false, ALARM_TYPE_ARMING);
    }
    else
    {
        if (userType != USERS_TYPE_UNKNOW)
        {
            Led_Set("LED_LOGO_B", LED_FLASH, 1, 2000);
            Led_Set("LED_OPEN", LED_FLASH, 1, 2000);
            Led_Set("LED_PWM_G", LED_ON, 0, 0);
            Led_Set("LED", LED_OFF, 0, 0); //关闭按键板灯光
            Led_Set("LED_LOCK", LED_ON, 0, 0);
        }

        /* 内门面板感应把手与双击OPEN的语音报，播报语音为：已开门*/
        if (userType == USERS_TYPE_TOUCH_HANDLE || userType == USERS_TYPE_OPEN_KEY || userType == USERS_TYPE_MACHINE_KEY)
        {
           // Audio_Play(YI_KAI_MEN, RESET);
        }
        if (LocalSub_GetArmingStatus() == ARMING_STA_ENTER)
        {
            LocalSub_SetAlarm(true, ALARM_TYPE_ARMING);
        }
    }

    if (userType != USERS_TYPE_MACHINE_KEY)
    {
        Audio_Play(YI_KAI_SUO, RESET);
    }
    // Led_Set("LED_CLOSE", LED_OFF, 0, 0);
	// Led_Set("LED_OPEN", LED_FLASH, 1, 2000);

    Local_LockSaveRecord(EVENT_TYPE_OPEN_CLOSE, userType, EVENT_CODE_UNLOCK, keysNum);
    uint8_t onceType = 0xff, onceNum = 0xff;
    ErrorStatus delStatu = SYS_CALL(Users_DelOnce, &onceType, &onceNum);
    if (delStatu == SUCCESS)
    {
        Local_LockSaveRecord(EVENT_TYPE_PROGRAM, onceType, EVENT_CODE_DELETE, onceNum);
    }
    local_LockExitSystemLock();
    Local_LockSetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS, false); //取消反锁状态

    LocalSub_SetAlarm(false, ALARM_TYPE_FORCE_UNLOCK);  //解除防撬报警
    LocalSub_SetAlarm(false, ALARM_TYPE_LOCK_ABNORMAL); //解除锁体异常报警
    LocalSub_SetAlarm(false, ALARM_TYPE_MECH_UNLOCK);   //解除机械钥匙开锁报警

    if (lockInfo.lock_type == LOCK_TYPE_824)
    {
        LocalSub_ExitStartArming();
    }
    LocalSub_SetArmingStatus(ARMING_STA_STOP); //布防停止

    uint8_t touchKeyLockCnt = 0;
    OSAL_NvWrite(SYS_OFFSET(touchKeyLockCnt), &touchKeyLockCnt, sizeof(touchKeyLockCnt)); //开锁成功 又可以恢复按前面板触摸上锁键5次
    SYS_CALL(Remote_SettingChangeReport);                                                 //设置状态上报
    OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
}

//处理上锁成功
static void Local_LockedSucceed(uint8_t userType)
{
    if (lockInfo.antiLockFlag == true)
    {
        LOCAL_LOCK_LOG("ANTI-LOCK succeed\r\n"); //已反锁
        Audio_Play(YI_FAN_SUO, RESET);
        Led_Set("LED", LED_OFF, 0, 0);
        Led_Set("LED13579", LED_FLASH, 2, 100);
        Led_Set("LED_PWM_R", LED_FLASH, 2, 100);
        Led_Set("LED_RED", LED_FLASH, 1, 500);

        Local_LockSetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS, true); //设置反锁状态
        //上报反锁状态
        SYS_CALL(Remote_SettingChangeReport); //设置状态上报
        if (lockInfo.lock_status == LOCK_ACTION_LOCKED || lockInfo.lock_status == LOCK_ACTION_LOCKED_MACH || lockInfo.lock_status == LOCK_ACTION_INVALID)
        {
            return; //已上锁状态
        }
    }
    else
    {
        Led_Set("LED_PWM_R", LED_ON, 0, 0);
    }

    LOCAL_LOCK_LOG("Locked succeed\r\n");
    Audio_Play(YI_GUAN_SUO, RESET);
    Led_Set("LED_OPEN", LED_OFF, 0, 0);
	Led_Set("LED_CLOSE", LED_FLASH, 1, 2000);

 //   Audio_Play(YI_GUAN_MEN, RESET);
 //   Led_Set("LED_CLOSE", LED_FLASH, 1, 2000);
    Local_LockSaveRecord(EVENT_TYPE_OPEN_CLOSE, userType, EVENT_CODE_LOCK, 0XFF); //保存上锁记录   P6老菜单上锁不需要存记录
    if (lockInfo.lock_type == LOCK_TYPE_824 && Menu_GetCurrentMenu() == MENU_MASTER &&
        lockInfo.lock_status != LOCK_ACTION_LOCKED && lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH &&
        lockInfo.lock_status != LOCK_ACTION_INVALID)
    {
        LocalSub_SetArmingStatus(ARMING_STA_START);
        OSAL_UpdateSleepTime(5000, 1);
    }

    if (lockInfo.userType == USERS_TYPE_PWD ||
        lockInfo.userType == USERS_TYPE_FPT ||
        lockInfo.userType == USERS_TYPE_CARD ||
        lockInfo.userType == USERS_TYPE_FACE ||
        lockInfo.userType == USERS_TYPE_APP)
    {
        LocalSub_SetAlarm(false, ALARM_TYPE_ARMING);       //取消布防报警
        LocalSub_SetAlarm(false, ALARM_TYPE_FORCE_UNLOCK); //取消防撬报警
    }
    LocalSub_SetAlarm(false, ALARM_TYPE_LOCK_ABNORMAL); //取消锁体异常报警
    LOCAL_LOCK_LOG("lockInfo.userType %02X\r\n", lockInfo.userType);
    if (lockInfo.userType != 0xff)
        OSAL_UpdateSleepTime(3000, 1); // 1000
    // local_DSensorDisable(5000); //关门成功后 人脸关闭5s
    Local_LockCancelAutoLock();
}

//处理门未上锁事件
static void Local_LockNotLocked(void)
{
    LOCAL_LOCK_LOG("Not locked\r\n");

    Audio_Play(MEN_WEI_SHANG_SUO, 2);
}

//处理锁体过流
static void Local_LockDciError(void)
{
    LOCAL_LOCK_LOG("DCI Error\r\n");
    Audio_Play(MEN_WEI_SHANG_SUO, SET);
}

//处理锁体异常事件
static void Local_LockAbnormal(void)
{
    LOCAL_LOCK_LOG("Lock abnormal\r\n");
    LocalSub_SetAlarm(true, ALARM_TYPE_LOCK_ABNORMAL);

    Local_LockCancelAutoLock();

    if (Local_LockGetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS) == true)
    {
        Local_LockSetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS, false); //取消反锁状态
                                                                //更新锁状态信息
        SYS_CALL(Remote_SettingChangeReport);                   //设置状态上报
    }
}

//处理锁体撬锁事件
static void Local_ForceUnlock(void)
{
    LOCAL_LOCK_LOG("Lock force unlock\r\n");
    LocalSub_SetAlarm(true, ALARM_TYPE_FORCE_UNLOCK);
}

/**
  * @brief  LOCK组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void Local_LockMsgCb(void *msg, uint16_t len)
{
    LockMsg_t *lock = (LockMsg_t *)msg;

    LOCAL_LOCK_LOG("Local_LockMsgCb, door_status:%d, lock_status:%d\r\n", lock->door, lock->lock);

    if (lock->lock == LOCK_ACTION_LOCKED || lock->lock == LOCK_ACTION_LOCKED_MACH) //上锁成功
    {
        Local_LockedSucceed(lockInfo.userType);
        // 上锁成功，打开休眠开锁检测
        Lock_SetSleepSenserCheck(SET);
    }
    #ifdef LOCK_524
    else if (lock->lock == LOCK_ACTION_UNLOCK_BACK) //开锁成功 524锁体不用回拖
    {

        Local_UnlockSucceed(lockInfo.userType, lockInfo.user_id);
    }
    #else
    else if (lock->lock == LOCK_ACTION_UNLOCK_NO_BACK) //开锁成功（开锁流程已结束，未回拖）
    {
        if (wakePullbackFlag == SET)
        {
            wakePullbackFlag = RESET;
        }
        else
        {
            Local_UnlockSucceed(lockInfo.userType, lockInfo.user_id);
        }
    }
    #endif
    else if (lock->lock == LOCK_ACTION_UNLOCK_MACH || lock->lock == LOCK_ACTION_UNLOCK) //机械开锁成功
    {
        uint8_t mode = Local_LockGetAmMode();

        if (lock->lock == LOCK_ACTION_UNLOCK_MACH)
        {
            Local_UnlockSucceed(USERS_TYPE_MACHINE_KEY, USERS_ID_MACHINE_KEY);
            Local_LockAutoLocked(5);//TODO: 是否要加这个？
        }
        else if (lock->lock == LOCK_ACTION_UNLOCK)
        {
            //LOCAL_LOCK_LOG("Unlock 001");
            Local_UnlockSucceed(lockInfo.userType, lockInfo.user_id);
        }

        if (mode != AUTO_MODE && lock->lock == LOCK_ACTION_UNLOCK_MACH)
        {
            // 如果当前不是自动模式，还能检测到机械开锁，同步上锁模式
            Lock_ModeSync(mode);
        }
        // if(lock->lock == LOCK_ACTION_UNLOCK_MACH)//机械钥匙开锁  要报警
        // {
        //     LocalSub_SetAlarm(true, ALARM_TYPE_MECH_UNLOCK); //设置机械钥匙报警
        // }
    }
    else if (lock->lock == LOCK_ACTION_NO_LOCKED)
    {
        Local_LockNotLocked();
    }
    else if (lock->lock == LOCK_ACTION_DCI_ERROR)
    {
        Local_LockDciError();
    }
    else if (lock->lock == LOCK_ACTION_ABNORMAL)
    {
        Local_LockAbnormal();
    }
    else if (lock->lock == LOCK_ACTION_FORCE_UNLOCK)
    {
        Local_ForceUnlock();
    }

    if (lockInfo.lock_type == LOCK_TYPE_BW) //霸王锁体要跟普通824反着来
    {
        if (lock->lock == LOCK_ACTION_UNLOCK_NO_BACK || lock->lock == LOCK_ACTION_DCI_ERROR || lock->lock == LOCK_ACTION_ABNORMAL)
        {
            Local_LockUnLockBack();
        }
    }
    else if (lockInfo.lock_type == LOCK_TYPE_824)
    {
        if (lock->lock == LOCK_ACTION_UNLOCK_NO_BACK || lock->lock == LOCK_ACTION_UNLOCK_MACH || lock->lock == LOCK_ACTION_UNLOCK)
        {
            Local_LockAutoLocked(0xff);
        }
    }

    if (lock->lock != LOCK_ACTION_INVALID)
    {
        lockInfo.lock_status = lock->lock;

        if (lock->lock == LOCK_ACTION_ABNORMAL)
        {
            sleepAutoLockedFlag = 2; //休眠前播放门未上锁
        }
        else
        {
            sleepAutoLockedFlag = 1; //休眠前执行自动上锁
        }
    }

    if (lockInfo.lock_type == LOCK_TYPE_824)
    {
        if (lock->door == USER_ACTION_RELEASE) //开门回拖
        {
            lockInfo.door_status = USER_ACTION_RELEASE;
            Local_LockControl(0xff, 0xff, LOCK_CTRL_UNLOCK_BACK);

            // if (lockInfo.lock_status == LOCK_ACTION_UNKNOW)//机械开锁没有到位，如果开门了，就要取消反锁
            //只要开门了，就要取消反锁
            {
                if (Local_LockGetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS) == true)
                {
                    Local_LockSetSysFlag(SYS_FLAG_ANTI_LOCK_STATUS, false); //取消反锁状态
                                                                            //更新锁状态信息
                    SYS_CALL(Remote_SettingChangeReport);                   //设置状态上报
                }
            }
        }
        else if (lock->door == USER_ACTION_LONG_PRESS) //关门上锁
        {
            lockInfo.door_status = USER_ACTION_LONG_PRESS;
            Local_LockAutoLockCallback(NULL);
        }

        if (lock->door != USER_ACTION_INVALID) //门状态变化：更新休眠时间
        {
            OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
        }
    }

    /* 长按button执行反锁（电机正在转）的过程中，如果收到了这三种动作不能清掉anti-lock标志 */
    if ((lock->lock != LOCK_ACTION_DCI_ERROR) && (lock->lock != LOCK_ACTION_BUSY) && (lock->lock!= LOCK_ACTION_INVALID))
    {
        lockInfo.antiLockFlag = false;
    }
}

/**
  * @brief  PSENSOR组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void Local_PsensorMsgCb(void *msg, uint16_t len)
{
    PsensorMsg_t *psensor = (PsensorMsg_t *)msg;

    LOCAL_LOCK_LOG("Local_PsensorMsgCb, %d\r\n", (uint16_t)psensor->msg);

    if (psensor->msg == PSENSOR_OPENED)
    {
        if (Local_LockGetAmMode() == AUTO_MODE) //自动模式
        {
            if (lockInfo.unlock_back == false)
            {
                Local_LockControl(LOCKED_TYPE_10S, 0XFF, LOCK_CTRL_UNLOCK_BACK);
                lockInfo.unlock_back = true;
            }
        }
        LOCAL_LOCK_LOG("door is open\r\n");
    }
    else if (psensor->msg == PSENSOR_CLOSED)
    {
        LOCAL_LOCK_LOG("door is close \r\n");
        if (Local_LockGetAmMode() == AUTO_MODE) //自动模式
        {
            if (lockInfo.lock_status == LOCK_ACTION_UNLOCK || lockInfo.lock_status == LOCK_ACTION_UNLOCK_BACK || lockInfo.lock_status == LOCK_ACTION_UNLOCK_NO_BACK || lockInfo.lock_status == LOCK_ACTION_UNLOCK_MACH || lockInfo.lock_status == LOCK_ACTION_UNLOCK_NO_BACK || lockInfo.lock_status == LOCK_ACTION_UNLOCK_MACH || lockInfo.lock_status == LOCK_ACTION_NO_LOCKED)
            {
                Local_LockControl(LOCKED_TYPE_10S, 0XFF, LOCK_CTRL_LOCKED);
                LOCAL_LOCK_LOG("door close by door sensor\r\n");
            }
        }
    }
    else if (psensor->msg == PSENSOR_CAL_FINISHED)
    {
        LOCAL_LOCK_LOG("calibration is finished\r\n");
    }
}

/**
  * @brief  锁体控制
  * @param  userType:密钥类型
  * @param  key_id:，密钥编号
  * @param  control:要控制的锁动作
  * @note   
  */ //   Local_LockControl(USERS_TYPE_KEY, 0xFF, LOCK_CTRL_VERIFY_OK);
ErrorStatus Local_LockControl(uint8_t userType, uint8_t key_id, LockCtrl_enum_t control)
{
    LOCAL_LOCK_LOG("lock control: %d, keysType: %d, user_id: %d, lock body: %d\r\n", control, userType, key_id, lockInfo.lock_type);

    if (control == LOCK_CTRL_VERIFY_OK)
    {

         LOCAL_LOCK_LOG(">>>>>>>lockInfo.lock_status:%d\n", lockInfo.lock_status);
         if (userType == USERS_TYPE_KEY)
            {
                //if (lockInfo.lock_status == LOCK_ACTION_UNLOCK || lockInfo.lock_status == LOCK_ACTION_UNLOCK_MACH )
                if (lockInfo.lock_status == LOCK_ACTION_UNLOCK )
                {
                    lockInfo.event_code = EVENT_CODE_LOCK;
                    control = LOCK_CTRL_LOCKED;
                    userType = LOCKED_INDOOR;
                }
                else
                {
                    control = LOCK_CTRL_UNLOCK;
                    userType = USERS_TYPE_OPEN_KEY;
                }
            }
        else
        {
            if (Local_LockGetAmMode() == MANUAL_MODE)
            {
                control = (lockInfo.lock_status == LOCK_ACTION_LOCKED || lockInfo.lock_status == LOCK_ACTION_LOCKED_MACH) ? LOCK_CTRL_UNLOCK : LOCK_CTRL_LOCKED;
            }
            else
            {
                control = LOCK_CTRL_UNLOCK;
            }
        }   
    }
    if (control == LOCK_CTRL_UNLOCK)
    {
        Local_LockAutoLocked(0xff);
        lockInfo.userType = userType;
        lockInfo.user_id = key_id;
        if (lockInfo.lock_type == LOCK_TYPE_BW)
        {
            SYS_CALL(Psensor_Calibration);
        }
    }
    else if (control == LOCK_CTRL_LOCKED)
    {
        lockInfo.userType = userType;
    }
    else if(control == LOCK_CTRL_LOCKED_KEY)
    {
        if (lockInfo.lock_status == LOCK_ACTION_UNLOCK )
        {
            lockInfo.event_code = EVENT_CODE_LOCK;
            control = LOCK_CTRL_LOCKED;
            lockInfo.userType = LOCKED_OUTDOOR;
        }
    }
    //Lock_Ctrl(control);
    Lock_Ctrl(userType,0x00,key_id,control);//TODO:调用该app的也要加个 event_code
    return SUCCESS;
}

/**
  * @brief  获取自动上锁定时器是否为空
  *
  */
TimerHandle_stu_t Local_LockGetAutoLockTimer(void)
{
    return lock_timer;
}

//获取触摸按键上锁按下次数  开一次门最多按5次可以上锁
uint8_t Local_LockGetTouchKeyLockTime(void)
{
    uint8_t touchKeyLockCnt = 0;
    OSAL_NvRead(SYS_OFFSET(touchKeyLockCnt), &touchKeyLockCnt, sizeof(touchKeyLockCnt));
    if (touchKeyLockCnt < 6)
    {
        touchKeyLockCnt++;
    }
    OSAL_NvWrite(SYS_OFFSET(touchKeyLockCnt), &touchKeyLockCnt, sizeof(touchKeyLockCnt));
    LOCAL_LOCK_LOG("touchKeyLockCnt:%d\r\n", touchKeyLockCnt);
    return touchKeyLockCnt;
}

/**
  * @brief  读取系统标志
  * @note
  *
  * @param  flag：SYS_FLAG_TAMPER_ALARM 防撬报警标志
  *               SYS_FLAG_ARMING_ALARM 布防报警标志
  *               SYS_FLAG_ARMING_STATUS 布防状态
  *               SYS_FLAG_ANTI_LOCK_STATUS 反锁状态
  *               SYS_FLAG_AGING_STATUS  老化状态
  *               SYS_FLAG_MECHKEY_ALARM 机械钥匙报警标志
  *
  * @return state：标志状态 true 和 false
  */
bool Local_LockGetSysFlag(uint8_t flag)
{
    uint8_t sys_flag = 0;
    OSAL_NvRead(SYS_OFFSET(sys_flag), &sys_flag, sizeof(sys_flag));
    return (sys_flag & flag) ? true : false;
}

/**
  * @brief  设置系统标志
  *
  * @param  flag：SYS_FLAG_TAMPER_ALARM 防撬报警标志
  *               SYS_FLAG_ARMING_ALARM 布防报警标志
  *               SYS_FLAG_ARMING_STATUS 布防状态
  *               SYS_FLAG_ANTI_LOCK_STATUS 反锁状态
  *               SYS_FLAG_AGING_STATUS  老化状态
  *               SYS_FLAG_MECHKEY_ALARM 机械钥匙报警标志
  *
  * @param state：true： 设置对应标志
  *               false：清除对应标志
  */
bool Local_LockSetSysFlag(uint8_t flag, bool state)
{
    uint8_t sys_flag = 0;
    OSAL_NvRead(SYS_OFFSET(sys_flag), &sys_flag, sizeof(sys_flag));
    if (state == true)
    {
        sys_flag |= flag;
    }
    else
    {
        sys_flag &= ~(flag);
    }
    return OSAL_NvWrite(SYS_OFFSET(sys_flag), &sys_flag, sizeof(sys_flag));
}

//保存一条记录，并上传服务器
void Local_LockSaveRecord(uint8_t event_type, uint8_t event_source, uint8_t event_code, uint8_t user_id)
{
    EventRecord_stu_t m_record;
    uint8_t activeStatu = SYS_CALL(Users_IsLockActived, NULL);
    __EFRAM static uint32_t lastRecordTimeStamp = 0;
    if (activeStatu == SUCCESS)
    {
    	if(event_code == EVENT_CODE_UNLOCK)
    	{
	        NvSystemParam_stu_t sysParam;
			OSAL_NvRead(0,&sysParam,sizeof(NvSystemParam_stu_t));
			sysParam.openLockTimes+=1;
			OSAL_NvWrite(SYS_OFFSET(openLockTimes), &sysParam.openLockTimes, 4);
    	}
        m_record.eventType = event_type;
        m_record.eventSource = event_source;
        m_record.eventCode = event_code;
        m_record.userID = user_id;
        m_record.appID = APP_ID_LOCAL;
        OSAL_TimeGet(&m_record.timestamp, T_UTC);
        if (m_record.timestamp == lastRecordTimeStamp)
        {
            m_record.timestamp += 1;
        }
        lastRecordTimeStamp = m_record.timestamp;
        LOCAL_LOCK_LOG("B2bSaveRecord  event_type:%d, event_source:%d, event_code:%d, user_id:%d, timestamp:%ld", event_type, event_source, event_code, user_id, m_record.timestamp);
        if(EVENT_TYPE_OPEN_CLOSE == event_type && event_code == EVENT_CODE_LOCK)
        {

        }
        else
        {
            if(event_code == EVENT_CODE_RESET)
            {
                m_record.timestamp += 3;//软件重启时间2.8秒左右
            }
            SYS_CALL(Record_Save, &m_record);
        }
        if (event_source == USERS_TYPE_EVIDENCE)
            SYS_CALL(Remote_RecordReport, &m_record);
        
        #if 1//VLINK    TODO: 记录完善      
            if(EVENT_TYPE_ALARM == event_type)
            {
                //SYS_CALL(Ble_alarm_report, &m_record);
            }
            else if(EVENT_TYPE_OPEN_CLOSE == event_type)
            {       
                //if(EVENT_TYPE_OPEN_CLOSE == event_type)
                //{
                    if(EVENT_CODE_UNLOCK == event_code)
                    {
                        SYS_CALL(Ble_unlock_record_report, &m_record);
                    }
                    else
                    {
                        SYS_CALL(Ble_locked_record_report, &m_record);
                    }
                    
                //}
            }
            else if(EVENT_TYPE_PROGRAM == event_type)
            {
                if(EVENT_CODE_DELETE == event_code)
                {
                    SYS_CALL(Ble_delkey_record_report, &m_record);
                }
                else if(EVENT_CODE_ADD == event_code)
                {
                    SYS_CALL(Ble_addkey_record_report, &m_record);
                }
            }

        #endif
    }
}

/**
  * @brief  设置反锁
  * 
  */
void Local_SetAntiLock(void)
{
    lockInfo.antiLockFlag = true;
    Local_LockControl(USERS_TYPE_OPEN_KEY, USERS_ID_SIGNAL, LOCK_CTRL_LOCKED);
}

/**
  * @brief  设置开门方向
  * @param  dir:方向  1：锁在门的左侧  2：锁在门的右侧
  * @note   
  */
ErrorStatus Local_LockSetDoorDirection(uint8_t dir)
{
    LOCAL_LOCK_LOG("Local_LockSetDoorDirection:%d\r\n", dir);
    /* TODO */
    return SUCCESS;
}

/**
  * @brief  设置带天地钩开锁
  * @param  power:天地钩  1：无天地钩  2：带天地钩
  * @note   
  */
ErrorStatus Local_LockSetOpenDoorPower(uint8_t power)
{
    LOCAL_LOCK_LOG("Local_LockSetOpenDoorPower:%d\r\n", power);
    /* TODO */
    return SUCCESS;
}

/**
  * @brief  获取手自动模式
  * @note   
  */
uint8_t Local_LockGetAmMode(void)
{
    uint8_t mode = 0;
    OSAL_NvRead(SYS_OFFSET(amMode), &mode, sizeof(mode));
    return mode;
}

/**
  * @brief  获取锁类型
  * @note   
  */
uint8_t Local_LockGetLockType(void)
{
    return lockInfo.lock_type;
}

/**
  * @brief  获取锁状态
  * @note   
  */
LockAction_enum_t local_LockGetLockStatus(void)
{
    return lockInfo.lock_status;
}

/**
  * @brief  更新锁自动上锁时间
  * @note   
  */
void Local_LockUpdateAutoLockTime(uint8_t time)
{
    lockInfo.auto_lock_time = time * 1000; // 转换成ms
    LOCAL_LOCK_LOG("Local_Lock UpdateAutoLockTime: %d\r\n", lockInfo.auto_lock_time);
}


void Local_LockProcessWakeSrc(uint32_t wake_src)
{
    LOCAL_LOCK_LOG("Local_LockProcessWakeSrc: %d\r\n", wake_src);
    uint32_t currentTime = OSAL_GetTickCount();
    #if 0
    if (wake_src == COMP_TOUCH || wake_src == COMP_FINGER || wake_src == COMP_CARD || wake_src == COMP_DSENSOR)
    {
        /* 手动模式/主锁舌未伸出：执行自动开锁 */
        if (Local_LockGetAmMode() == MANUAL_MODE && lockInfo.lock_status != LOCK_ACTION_LOCKED &&
            lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH && lockInfo.door_status != USER_ACTION_RELEASE)
        {
            wakePullbackFlag = SET;
            Local_LockControl(0xff, 0xff, LOCK_CTRL_UNLOCK);
        }
    }
    else if (wake_src == COMP_LOCK)
    #endif
    {
        // 唤醒 当前正在自动上锁计时
        if (autoLockStartTime != 0)
        {
            // 更新剩余时间
            autoLockRemainTime = lockInfo.auto_lock_time - OSAL_PastTime(currentTime, autoLockStartTime);
            LOCAL_LOCK_LOG("wake auto lock remain time %d %d\r\n", autoLockStartTime, autoLockRemainTime);

            // if ()
            {

                if (updataRemainTime_timer != NULL)
                {
                    OSAL_TimerDelete(updataRemainTime_timer);
                    updataRemainTime_timer = NULL;
                }
                // 1S定时器更新剩余时间
                updataRemainTime_timer = OSAL_TimerCreate(Local_LockRemainTimeUpdateCallback, AUTO_UPDATE_TIME, SET);
            }
        }
    }
}

ErrorStatus Lock_SleepProcess(void)
{
    ErrorStatus status = SUCCESS;

    if (sleepAutoLockedFlag == 1)
    {
        if (lockInfo.lock_status != LOCK_ACTION_LOCKED && lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH)
        {
            if (autoLockRemainTime == 0 || updataRemainTime_timer == NULL)
            {
                LOCAL_LOCK_LOG("Lock_SleepProcess auto lock\r\n");
                Local_LockAutoLockCallback(NULL);
            }

            status = ERROR;
        }
    }
    else if (sleepAutoLockedFlag == 2)
    {
        if ((lockInfo.door_status == USER_ACTION_LONG_PRESS || lockInfo.door_status == USER_ACTION_PRESS)
          && (lockInfo.lock_status != LOCK_ACTION_LOCKED && lockInfo.lock_status != LOCK_ACTION_LOCKED_MACH))
        {
            Audio_Play(MEN_WEI_SHANG_SUO, 2);
            status = ERROR;
        }
    }
    sleepAutoLockedFlag = 0;
    wakePullbackFlag = RESET;

    // 休眠前去除自动上锁更新时间定时器
    LOCAL_LOCK_LOG("Lock_SleepProcess del updateRemainTime_timer\r\n");
    if (updataRemainTime_timer != NULL)
    {
        OSAL_TimerDelete(updataRemainTime_timer);
        updataRemainTime_timer = NULL;
    }

    return status;
}

/**
  * @brief  锁应用初始化
  * @note   
  *
  * @param  app_handle：创建应用时传进的句柄
  * @param  
  * @return void
  */
void Local_LockInit(AppHandle_t app_handle)
{
    __EFRAM static uint8_t firstPowerOn = 1;
    
    if (firstPowerOn)
    {
        firstPowerOn = 0;
        lockInfo.user_id = 0xFF;
        lockInfo.userType = 0xFF;
        lockInfo.lock_status = (LockAction_enum_t)LOCK_ACTION_INVALID;
        lockInfo.antiLockFlag = false;
        OSAL_NvRead(SYS_OFFSET(lock_type), &lockInfo.lock_type, sizeof(lockInfo.lock_type));
#if defined(DEFAULT_AUTO_LOCK_TIME)
        uint8_t nv_autoLockTime = DEFAULT_AUTO_LOCK_TIME;
        OSAL_NvRead(SYS_OFFSET(auto_lock_time), &nv_autoLockTime, sizeof(nv_autoLockTime));
        lockInfo.auto_lock_time = nv_autoLockTime * 1000; // 转换成ms
        LOCAL_LOCK_LOG("lockInfo.lock_time:%d\r\n",lockInfo.auto_lock_time);
#else
        if (lockInfo.lock_type == LOCK_TYPE_BW)
        {
            lockInfo.auto_lock_time = 15000;
        }
        else if (lockInfo.lock_type == LOCK_TYPE_824)
        {
            lockInfo.auto_lock_time = 10000;
        }
        else if (lockInfo.lock_type == LOCK_TYPE_524)
        {
            lockInfo.auto_lock_time = 5000;
        }
        else if (lockInfo.lock_type == LOCK_TYPE_DAI)
        {
            lockInfo.auto_lock_time = 10000; //
        }
#endif
        LOCAL_LOCK_LOG("lockInfo.lock_type:%d\r\n",lockInfo.lock_type);
    }
    SYS_API(Local_LockControl);
    SYS_API(local_LockGetLockStatus);
    SYS_API(Local_LockUpdateAutoLockTime);
    sleepAutoLockedFlag = 0;
    OSAL_MessageSubscribe(app_handle, COMP_LOCK, Local_LockMsgCb);
    OSAL_MessageSubscribe(app_handle, COMP_PSENSOR, Local_PsensorMsgCb);
}
